package com.restphp.java.hashdb.dcs.server;

import com.alibaba.fastjson.JSONObject;
import com.restphp.java.hashdb.core.HashDbCore;
import com.restphp.java.hashdb.dcs.constant.MessageType;
import com.restphp.java.hashdb.dcs.po.Message;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.internal.StringUtil;

import java.io.UnsupportedEncodingException;

/**
 * 处理方法.
 * Created by sofical on 2020/8/11.
 */
public class HashDbClusterEchoServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        //System.out.println(ctx.channel().localAddress().toString() + " 通道已激活！");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        //System.out.println(ctx.channel().localAddress().toString() + " 通道不活跃！");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buf = (ByteBuf) msg;
        String rev = getMessage(buf);
        //System.out.println("客户端收到服务器数据:" + rev);

        if (!StringUtil.isNullOrEmpty(rev)) {
            //System.out.println("start check request");
            Message message = JSONObject.parseObject(rev, Message.class);

            if (null != message) {
                HashDbCore.startup(message.getRoot(), null);
                if (MessageType.GET.equals(message.getMessageType())) {
                    //读取
                    //System.out.println("读取缓存数据");
                    String info = HashDbCore.get(message.getRoot(), message.getTable(), message.getKey(), String.class);
                    //System.out.println("获取到缓存数据：" + info);
                    ctx.write(Unpooled.wrappedBuffer(info.getBytes()));
                } else if (MessageType.SET.equals(message.getMessageType())) {
                    //设置.
                    //System.out.println("设置键置");
                    HashDbCore.set(message.getRoot(), message.getTable(), message.getKey(), message.getValue(), message.getTimeout(), message.getTime());
                    //System.out.println("设置键置结束");
                } else if (MessageType.DELETE.equals(message.getMessageType())) {
                    //删除
                    //System.out.print("删除键值");
                    HashDbCore.delete(message.getRoot(), message.getTable(), message.getKey(), message.getTime());
                    //System.out.print("删除键值结束");
                } else {
                    //System.out.print("不支持的操作类型");
                }
            }
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        //System.out.println("服务端接收数据完毕..");
        ctx.writeAndFlush(Unpooled.BIG_ENDIAN).addListener(ChannelFutureListener.CLOSE);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
        //System.out.println("异常信息：\r\n" + cause.getMessage());
    }

    private String getMessage(ByteBuf buf) {
        byte[] con = new byte[buf.readableBytes()];
        buf.readBytes(con);
        try {
            return new String(con, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }
}
